#pragma once

#include <string>
using namespace std;

#include "topdbs_common.hpp"
#include "topdbs_error.hpp"
#include "topdbs_field.hpp"
#include "topdbs_base_connection.hpp"

namespace topdbs
{
	class topdbs_base_session 
		: public topdbs_error
	{	
	protected:
		eDBSCommandType_t    m_commandType;
		std::string          m_commandText;
		stringmap_row_t m_row;
		stringmap_rs_t  m_res;	
		bool m_isResultSet;
		int m_data_index;
		int m_sqlrows;
		bool m_isExecuted;
		bool m_isPrepared;
		std::vector<string> m_commandFields;
		int m_numParams;
		//topdbs_base_connection* m_pConnection;
		//topdbs_base_session* m_pSession;
	public:	
		topdbs_base_session();
		//topdbs_base_session(topdbs_base_connection* pConnection);
		virtual ~topdbs_base_session();

		//void setConnection(topdbs_base_connection* pConnection);
		//topdbs_base_connection* getConnection() const;
		//bool status();
		void setCommandText(const string& sSQL,eDBSCommandType_t commandType = DBS_CmdUnknown);
		string& getCommandText();
		eDBSCommandType_t CommandType() const; 

		stringmap_row_t& getRow();
		stringmap_rs_t&  getResult();

		//! Tests whether a result set exists after the command execution.
		bool isResultSet() const ;
		//! Returns number of rows affected by last DML operation.
		long RowsAffected() const ;
		//! Returns isExecuted
		bool IsExecuted() const { return m_isExecuted; };	
		//! Returns fetch field value.
		int  GetField(const std::string& iField,std::string& oValue);
		int  GetField(const std::string& iField,char* oValue);
		int  GetField(const std::string& iField,int&  oValue);
		int  GetField(const std::string& iField,long& oValue);	
		//! simple replace params
		int  ReplaceParams(int paramno,const DBSValue& value);
		//! Returns the current command params num
		int  NumsParams() { return m_numParams; };	

		//! virtual function interface 
		//! reset the current command all info.
		virtual void Reset();
		//! Validates and prepares the current command for execution.
		//! Postgresql not support ? or : 
		virtual int  Prepare() = 0;
		//! Executes the current command.
		virtual int  Execute() = 0; 
		virtual int  Execute(const char* sSQL,...)  = 0; 	
		virtual int  ExecuteV(const string& sSQL,va_list vaList);
		virtual int  ExecuteFetch(const string& sSQL) = 0;
		//! Fetches next row from a result set.
		virtual bool FetchNext();
		//! Fetches next row from a result cursor.
		virtual bool FetchCursorNext(uint16_t nFetchSize = TOPDBS_DEFAULT_FETCH_SIZE) = 0;	
		//! Binding the command parameter specified by its position
		virtual int  BindParams(const uint16_t paramno,const DBSValue& value) = 0;
		virtual int  BindParams(const uint16_t paramno,const string& value)   = 0;
		virtual int  BindParams(const uint16_t paramno,const int     value)   = 0;
		virtual int  BindParams(const uint16_t paramno,const long    value)   = 0;
		virtual int  BindParams(const uint16_t paramno,const float   value)   = 0;
		virtual int  BindParams(const uint16_t paramno,const double  value)   = 0;
	};
}